package net.cctms.zhishu.webAppFramework.video;

import android.app.Service;
import android.content.Context;
import android.media.AudioManager;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;


import net.cctms.zhishu.R;
import net.cctms.zhishu.webAppFramework.material.MaterialProgressWheel;
import net.cctms.zhishu.webAppFramework.utils.Log;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 类名 NiceVideoPlayerController
 * 作者 Keyu Chan
 * 创建日期 2017/9/5
 * 邮箱 chenky@corp.21cn.com
 * 说明 播放器控制器
 */
public class NiceVideoPlayerController extends FrameLayout
        implements View.OnClickListener,
        SeekBar.OnSeekBarChangeListener, AudioManager.OnAudioFocusChangeListener {

    private Context mContext;
    private NiceVideoPlayerControl mNiceVideoPlayer;
    private ImageView mCenterStart;
    private ImageView mBack;
    private ImageView mRestartPause;
    private TextView mPosition;
    private TextView mDuration;
    private SeekBar mSeek;
    private ImageView mFullScreen;
    private LinearLayout mCompleted;
    private TextView mReplay;
    private TextView mShare;
    private MaterialProgressWheel mCenterLoading;
    private RelativeLayout mBottom;

    private Timer mUpdateProgressTimer;
    private TimerTask mUpdateProgressTimerTask;
    private boolean topBottomVisible;
    private CountDownTimer mDismissTopBottomCountDownTimer;
    private AudioManager mAudioManager;
    private OnControllerListener onControllerListener;

    private boolean isError;//用于记录Player是否播放出错

    public NiceVideoPlayerController(Context context) {
        super(context);
        mContext = context;
        init();
    }

    private void init() {
        LayoutInflater.from(mContext).inflate(R.layout.nice_video_palyer_controller, this, true);
        mCenterStart = (ImageView) findViewById(R.id.center_start);

        mBack = (ImageView) findViewById( R.id.back);

        mRestartPause = (ImageView) findViewById(R.id.restart_or_pause);
        mPosition = (TextView) findViewById(R.id.position);
        mDuration = (TextView) findViewById(R.id.duration);
        mSeek = (SeekBar) findViewById(R.id.seek);
        mFullScreen = (ImageView) findViewById(R.id.full_screen);
        mBottom = (RelativeLayout) findViewById(R.id.bottom);

        mCompleted = (LinearLayout) findViewById(R.id.completed);
        mReplay = (TextView) findViewById(R.id.replay);
        mShare = (TextView) findViewById(R.id.share);

        mCenterLoading = (MaterialProgressWheel) findViewById(R.id.center_loading);

        mCenterStart.setOnClickListener(this);
        mBack.setOnClickListener(this);
        mRestartPause.setOnClickListener(this);
        mFullScreen.setOnClickListener(this);
        mReplay.setOnClickListener(this);
        mShare.setOnClickListener(this);
        mSeek.setOnSeekBarChangeListener(this);
        this.setOnClickListener(this);

        mAudioManager = (AudioManager) mContext.getSystemService(Service.AUDIO_SERVICE);
        //mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    }

    public void setNiceVideoPlayer(NiceVideoPlayerControl niceVideoPlayer) {
        mNiceVideoPlayer = niceVideoPlayer;
    }

    public void setOnControllerListener(OnControllerListener onControllerListener) {
        this.onControllerListener = onControllerListener;
    }

    @Override
    public void onClick(View v) {
        if (v == mCenterStart) {
            if (mNiceVideoPlayer.isIdle()) {
                mNiceVideoPlayer.start();
            }
        } else if (v == mBack) {
            if (onControllerListener != null) {
                onControllerListener.onCloseClick();
            }
        } else if (v == mRestartPause) {
            if (mNiceVideoPlayer.isPlaying() || mNiceVideoPlayer.isBufferingPlaying()) {
                mNiceVideoPlayer.pause();
            } else if (mNiceVideoPlayer.isPaused() || mNiceVideoPlayer.isBufferingPaused()) {
                mNiceVideoPlayer.restart();
            }
        } else if (v == mFullScreen) {
            if (mNiceVideoPlayer.isNormal()) {
                mNiceVideoPlayer.enterFullScreen();
            } else if (mNiceVideoPlayer.isFullScreen()) {
                mNiceVideoPlayer.exitFullScreen();
            }
        } else if (v == mShare) {
            if (onControllerListener != null) {
                Log.i("VideoController", "onControllerListener.onShareClick()");
                onControllerListener.onShareClick();
            }
        } else if (v == this) {
            if (mNiceVideoPlayer.isPlaying()
                    || mNiceVideoPlayer.isPaused()
                    || mNiceVideoPlayer.isBufferingPlaying()
                    || mNiceVideoPlayer.isBufferingPaused()) {
                setTopBottomVisible(!topBottomVisible);
            }
        }
    }

    private void setTopBottomVisible(boolean visible) {
        topBottomVisible = visible;
        if (visible) {
            if (!mNiceVideoPlayer.isPaused() && !mNiceVideoPlayer.isBufferingPaused()) {
                startDismissTopBottomTimer();
            }
        } else {
            cancelDismissTopBottomTimer();
        }
    }

    public void setControllerState(int playerState, int playState) {
        switch (playerState) {
            case NiceVideoPlayer.PLAYER_NORMAL:
                mFullScreen.setVisibility(View.VISIBLE);
                mFullScreen.setImageResource(R.mipmap.video_scale);
                break;
            case NiceVideoPlayer.PLAYER_FULL_SCREEN:
                mFullScreen.setVisibility(View.VISIBLE);
                mFullScreen.setImageResource(R.mipmap.video_has_scale);
                break;
            case NiceVideoPlayer.PLAYER_TINY_WINDOW:
                mFullScreen.setVisibility(View.GONE);
                break;
        }
        switch (playState) {
            case NiceVideoPlayer.STATE_IDLE:
                break;
            case NiceVideoPlayer.STATE_PREPARING:
                // 只显示准备中动画，其他不显示
                mCompleted.setVisibility(View.GONE);
                mCenterStart.setVisibility(View.GONE);
                mCenterLoading.setVisibility(View.VISIBLE);
                mBottom.setVisibility(VISIBLE);
                isError = false;
                Log.i("VideoController", "STATE_PREPARING");
                break;
            case NiceVideoPlayer.STATE_PREPARED:
                startUpdateProgressTimer();
                mCompleted.setVisibility(GONE);
                mCenterLoading.setVisibility(View.GONE);
                mBottom.setVisibility(VISIBLE);
                isError = false;
                Log.i("VideoController", "STATE_PREPARED");
                break;
            case NiceVideoPlayer.STATE_PLAYING:
                mCompleted.setVisibility(GONE);
                mCenterStart.setVisibility(View.GONE);
                mRestartPause.setImageResource(R.mipmap.video_pause);
                mCenterLoading.setVisibility(View.GONE);
                mBottom.setVisibility(VISIBLE);
                isError = false;
                startDismissTopBottomTimer();
                Log.i("VideoController", "STATE_PLAYING");
                break;
            case NiceVideoPlayer.STATE_PAUSED:
                mCompleted.setVisibility(GONE);
                mCenterStart.setVisibility(View.GONE);
                mCenterLoading.setVisibility(View.GONE);
                mCenterStart.setVisibility(View.VISIBLE);
                mRestartPause.setImageResource(R.mipmap.video_play_small);
                mBottom.setVisibility(VISIBLE);
                isError = false;
                cancelDismissTopBottomTimer();
                Log.i("VideoController", "STATE_PAUSED");
                break;
            case NiceVideoPlayer.STATE_BUFFERING_PLAYING:
                mCompleted.setVisibility(GONE);
                mCenterLoading.setVisibility(View.VISIBLE);
                mRestartPause.setImageResource(R.mipmap.video_pause);
                mBottom.setVisibility(VISIBLE);
                isError = false;
                startDismissTopBottomTimer();
                Log.i("VideoController", "STATE_BUFFERING_PLAYING");
                break;
            case NiceVideoPlayer.STATE_BUFFERING_PAUSED:
                isError = false;
                mCompleted.setVisibility(GONE);
                mCenterLoading.setVisibility(View.VISIBLE);
                mRestartPause.setImageResource(R.mipmap.video_play_small);
                mBottom.setVisibility(VISIBLE);
                cancelDismissTopBottomTimer();
                Log.i("VideoController", "STATE_BUFFERING_PAUSED");
                break;
            case NiceVideoPlayer.STATE_COMPLETED:
                Log.i("VideoController", "STATE_COMPLETED");
                cancelUpdateProgressTimer();
                setTopBottomVisible(false);
                //播放器播放失败后依然回回调播放完成状态，所以
                //需要判断如果是失败状态则完成界面不能显示
                if (!isError) {
                    mCompleted.setVisibility(View.VISIBLE);
                } else {
                    mCompleted.setVisibility(GONE);
                }
                mCenterLoading.setVisibility(View.GONE);
                mBottom.setVisibility(GONE);
                if (mNiceVideoPlayer.isFullScreen()) {
                    mNiceVideoPlayer.exitFullScreen();
                }
                break;
            case NiceVideoPlayer.STATE_ERROR:
                Log.i("VideoController", "STATE_ERROR");
                isError = true;
                if (onControllerListener != null) {
                    onControllerListener.onPlayerError();
                }
                cancelUpdateProgressTimer();
                setTopBottomVisible(false);
                break;
        }
    }

    private void startUpdateProgressTimer() {
        cancelUpdateProgressTimer();
        if (mUpdateProgressTimer == null) {
            mUpdateProgressTimer = new Timer();
        }
        if (mUpdateProgressTimerTask == null) {
            mUpdateProgressTimerTask = new TimerTask() {
                @Override
                public void run() {
                    NiceVideoPlayerController.this.post(new Runnable() {
                        @Override
                        public void run() {
                            updateProgress();
                        }
                    });
                }
            };
        }
        mUpdateProgressTimer.schedule(mUpdateProgressTimerTask, 0, 300);
    }

    private void updateProgress() {
        long position = mNiceVideoPlayer.getCurrentPosition();
        long duration = mNiceVideoPlayer.getDuration();
        int bufferPercentage = mNiceVideoPlayer.getBufferPercentage();
        mSeek.setSecondaryProgress(bufferPercentage);
        int progress = (int) (100f * position / duration);
        mSeek.setProgress(progress);
        mPosition.setText(NiceUtil.formatTime(position));
        mDuration.setText(NiceUtil.formatTime(duration));

        if (onControllerListener != null) {
            onControllerListener.onPlayProgress(position, duration);
        }
    }

    private void cancelUpdateProgressTimer() {
        if (mUpdateProgressTimer != null) {
            mUpdateProgressTimer.cancel();
            mUpdateProgressTimer = null;
        }
        if (mUpdateProgressTimerTask != null) {
            mUpdateProgressTimerTask.cancel();
            mUpdateProgressTimerTask = null;
        }
    }

    private void startDismissTopBottomTimer() {
        cancelDismissTopBottomTimer();
        if (mDismissTopBottomCountDownTimer == null) {
            mDismissTopBottomCountDownTimer = new CountDownTimer(2000, 2000) {
                @Override
                public void onTick(long millisUntilFinished) {

                }

                @Override
                public void onFinish() {
                    setTopBottomVisible(false);
                }
            };
        }
        mDismissTopBottomCountDownTimer.start();
    }


    private void cancelDismissTopBottomTimer() {
        if (mDismissTopBottomCountDownTimer != null) {
            mDismissTopBottomCountDownTimer.cancel();
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        cancelDismissTopBottomTimer();
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (mNiceVideoPlayer.isBufferingPaused() || mNiceVideoPlayer.isPaused()) {
            mNiceVideoPlayer.restart();
        }
        int position = (int) (mNiceVideoPlayer.getDuration() * seekBar.getProgress() / 100f);
        mNiceVideoPlayer.seekTo(position);
        startDismissTopBottomTimer();
    }

    /**
     * 控制器恢复到初始状态
     */
    public void reset() {
        topBottomVisible = false;
        cancelUpdateProgressTimer();
        cancelDismissTopBottomTimer();
        mSeek.setProgress(0);
        mSeek.setSecondaryProgress(0);

        mCenterStart.setVisibility(View.VISIBLE);
        mFullScreen.setImageResource(R.mipmap.video_scale);
        mCompleted.setVisibility(View.GONE);
    }


    public void onActivityPause() {
        //mNiceVideoPlayer.pause();
        //mAudioManager.abandonAudioFocus(this);
    }

    public void onActivityReStart() {
        //mNiceVideoPlayer.restart();
        //mAudioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
    }

    public void onActivityDestroy() {
        mNiceVideoPlayer.release();
        //mAudioManager.abandonAudioFocus(this);
    }

    @Override
    public void onAudioFocusChange(int focusChange) {
//        switch (focusChange) {
//            case AudioManager.AUDIOFOCUS_LOSS:
//            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
//            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
//                if (mNiceVideoPlayer.isPlaying()) {
//                    mNiceVideoPlayer.pause();
//                }
//                break;
//        }
    }

    public interface OnControllerListener {
        void onCloseClick();

        void onShareClick();

        void onPlayerError();

        void onPlayProgress(long position, long duration);
    }
}
